﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Serialization;

namespace OrderManagement
{
    public class Order : IEquatable<Order>
    {
        public int OrderId { get; set; }
        public string Customer { get; set; }
        public List<OrderDetails> OrderDetails { get; set; }
        public double TotalAmount => OrderDetails.Sum(od => od.Amount);

        public override bool Equals(object obj)
        //用于处理所有类型的对象比较，并在内部调用类型安全的 Equals(Order other) 方法。
        {
            return Equals(obj as Order);
        }

        public bool Equals(Order other)
        {
            return other != null && OrderId == other.OrderId;
        }

        public override int GetHashCode()
        {
            return OrderId.GetHashCode();
        }

        public override string ToString()
        {
            return $"OrderId: {OrderId}, Customer: {Customer}, TotalAmount: {TotalAmount}";
        }
    }

    public class OrderDetails : IEquatable<OrderDetails>
    {
        public string ProductName { get; set; }
        public int Quantity { get; set; }
        public double Price { get; set; }
        public double Amount => Quantity * Price;

        public override bool Equals(object obj)
        {
            return Equals(obj as OrderDetails);
        }

        public bool Equals(OrderDetails other)
        {
            return other != null && ProductName == other.ProductName;
        }

        public override int GetHashCode()
        {
            return ProductName.GetHashCode();
        }

        public override string ToString()
        {
            return $"ProductName: {ProductName}, Quantity: {Quantity}, Price: {Price}, Amount: {Amount}";
        }
    }

    public class OrderService
    {
        private List<Order> orders = new List<Order>();

        public void AddOrder(Order order)
        {
            if (orders.Contains(order))
            {
                throw new Exception("Order with the same ID already exists.");
            }
            orders.Add(order);
        }

        public void RemoveOrder(int orderId)
        {
            var order = orders.FirstOrDefault(o => o.OrderId == orderId);
            if (order != null)
            {
                orders.Remove(order);
            }
            else
            {
                throw new Exception("Order not found.");
            }
        }

        public void UpdateOrder(Order updatedOrder)
        {
            var order = orders.FirstOrDefault(o => o.OrderId == updatedOrder.OrderId);
            if (order != null)
            {
                order.Customer = updatedOrder.Customer;
                order.OrderDetails = updatedOrder.OrderDetails;
                Console.WriteLine($"Order {order.OrderId} updated.");
            }
            else
            {
                throw new Exception("Order not found.");
            }
        }

        public List<Order> QueryOrders(Func<Order, bool> predicate)
        {
            return orders.Where(predicate).OrderBy(o => o.TotalAmount).ToList();
        }

        public List<Order> GetAllOrders()
        {
            return orders.OrderBy(o => o.OrderId).ToList();
        }

        public List<Order> GetAllOrders(Func<Order, object> orderBy)
        {
            return orders.OrderBy(orderBy).ToList();
        }

        public void Export(string filePath)
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Order>));
            using (FileStream fs = new FileStream(filePath, FileMode.Create))
            {
                xmlSerializer.Serialize(fs, orders);
            }
        }

        public void Import(string filePath)
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Order>));
            using (FileStream fs = new FileStream(filePath, FileMode.Open))
            {
                orders = (List<Order>)xmlSerializer.Deserialize(fs);
            }
        }

    }

    class Program
    {
        static void Main(string[] args)
        {
            OrderService orderService = new OrderService();

            // 添加订单
            Order order1 = new Order
            {
                OrderId = 1,
                Customer = "Alice",
                OrderDetails = new List<OrderDetails>
                {
                    new OrderDetails { ProductName = "Product1", Quantity = 2, Price = 10 },
                    new OrderDetails { ProductName = "Product2", Quantity = 1, Price = 20 }
                }
            };
            orderService.AddOrder(order1);

            // 查询订单
            var orders = orderService.QueryOrders(o => o.Customer == "Alice");
            foreach (var order in orders)
            {
                Console.WriteLine(order);
            }

            // 修改订单
            order1.Customer = "Bob";
            orderService.UpdateOrder(order1);

            // 显示订单
            var allOrders = orderService.GetAllOrders();
            foreach (var order in allOrders)
            {
                Console.WriteLine(order);
            }

            // 测试导出订单
            string filePath = "D://orders.xml";
            orderService.Export(filePath);
            Console.WriteLine($"Orders exported to {filePath}");

            // 测试导入订单
            orderService.Import(filePath);
            var allOrder = orderService.GetAllOrders();
            foreach (var order in allOrder)
            {
                Console.WriteLine(order);
            }

            // 删除订单
            try
            {
                orderService.RemoveOrder(1);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }          
        }
    }
}

